package com.cmii.sjw.department.control.jsc.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cmii.sjw.department.control.jsc.mapper.RoleMapper;
import com.cmii.sjw.department.control.jsc.mapper.RoleMenuMapper;
import com.cmii.sjw.department.control.jsc.model.User;
import com.cmii.sjw.department.control.jsc.model.dto.RoleQueryDTO;
import com.cmii.sjw.department.control.jsc.model.entity.Role;
import com.cmii.sjw.department.control.jsc.model.entity.RoleMenu;
import com.cmii.sjw.department.control.jsc.model.entity.UserRole;
import com.cmii.sjw.department.control.jsc.service.IUserService;
import com.cmii.sjw.department.control.jsc.service.RoleService;
import com.cmii.sjw.department.control.jsc.service.UserRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author jfh
 * @Date 2025-04-08 周二 15:43
 * @Version 1.0
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    @Autowired
    private RoleMenuMapper roleMenuMapper;

    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    private IUserService userService;

    @Override
    public boolean saveRoleWithMenus(Role role, List<Long> menuIds) {
        if(role.getId() == null) {
            role.setCreateTime(new Date());
        }
        else {
            role.setUpdateTime(new Date());
        }
        // 添加角色名称唯一性校验
        Long count = this.lambdaQuery()
                .eq(Role::getRoleName, role.getRoleName())
                .eq(Role::getStatus, 0)
                .ne(role.getId() != null, Role::getId, role.getId())
                .count();
        if (count > 0) {
            throw new RuntimeException("角色名称已存在");
        }
        // 保存角色基本信息
        this.saveOrUpdate(role);

        // 删除原有菜单关联
        roleMenuMapper.deleteByRoleId(role.getId());

        if (!CollectionUtils.isEmpty(menuIds)) {
            // 构建角色菜单关联关系
            List<RoleMenu> roleMenus = menuIds.stream()
                    .map(menuId -> new RoleMenu().setRoleId(role.getId()).setMenuId(menuId))
                    .collect(Collectors.toList());

            // 批量插入新关联
            roleMenuMapper.batchInsertRoleMenus(roleMenus);
        }
        return true;
    }

    @Override
    public List<Long> getMenuIdsByRoleId(Long roleId) {
        return roleMenuMapper.selectList(new LambdaQueryWrapper<RoleMenu>()
                        .eq(RoleMenu::getRoleId, roleId))
                .stream()
                .map(RoleMenu::getMenuId)
                .collect(Collectors.toList());
    }

    @Override
    public boolean deleteRole(Long id) {
        // 检查是否有用户关联
        Long userCount = userRoleService.count(new LambdaQueryWrapper<UserRole>()
                .eq(UserRole::getRoleId, id));
        if (userCount > 0) {
            throw new RuntimeException("角色下存在用户，无法删除");
        }
        // 2. 删除角色关联的菜单权限
        roleMenuMapper.deleteByRoleId(id);
        return this.removeById(id);
    }

    @Override
    public boolean updateRoleStatus(Long id, Integer status) {
        Role role = new Role();
        role.setId(id);
        role.setStatus(status);
        return this.updateById(role);
    }

    @Override
    public Page<Role> getRolePage(RoleQueryDTO queryDTO) {
        return this.lambdaQuery()
                .like(StringUtils.hasText(queryDTO.getRoleName()), Role::getRoleName, queryDTO.getRoleName())
                .like(StringUtils.hasText(queryDTO.getDescription()), Role::getDescription, queryDTO.getDescription())
                .eq(queryDTO.getStatus() != null, Role::getStatus, queryDTO.getStatus())
                .orderByDesc(Role::getCreateTime) // 按创建时间倒序排序
                .page(new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize()));
    }

    @Override
    public boolean assignUsersToRole(Long roleId, List<Long> userIds) {
        // 添加角色存在性校验
        if (this.getById(roleId) == null) {
            throw new RuntimeException("角色不存在");
        }

        // 添加用户存在性校验
        if (!CollectionUtils.isEmpty(userIds)) {
            Long actualUserCount = userService.count(new LambdaQueryWrapper<User>()
                    .in(User::getUserId, userIds));
            if (actualUserCount != userIds.size()) {
                throw new RuntimeException("存在无效用户ID");
            }
        }
        // 删除原有关联
        userRoleService.remove(new LambdaQueryWrapper<UserRole>()
                .eq(UserRole::getRoleId, roleId));

        // 建立新关联
        if (!CollectionUtils.isEmpty(userIds)) {
            List<UserRole> userRoles = userIds.stream()
                    .map(userId -> new UserRole().setRoleId(roleId).setUserId(userId))
                    .collect(Collectors.toList());
            return userRoleService.saveBatch(userRoles);
        }
        return true;
    }

    @Override
    public boolean batchDisableStatus(Long[] ids) {
        if (ids == null || ids.length == 0) {
            return false;
        }
        return baseMapper.batchDisableStatus(Arrays.asList(ids)) > 0;
    }

    @Override
    public boolean batchActivationStatus(Long[] ids) {
        if (ids == null || ids.length == 0) {
            return false;
        }
        return baseMapper.batchActivationStatus(Arrays.asList(ids)) > 0;
    }

}
